package net.zapasa.core.common.util;

import java.net.URL;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.helpers.Loader;

public class LogUtil {

	private static final Logger LOGGER = Logger.getLogger(LogUtil.class);
	private static final int TRACE = 5000;
	private static final int WARN = 30000;
	private static final String DEFAULT_CONFIG_URL = "log4j.properties";
	private static final String DEFAULT_ERR_MSG = "Logger no funciona apropiadamente. ";

	static {
		try {
			URL url = Loader.getResource(DEFAULT_CONFIG_URL);
			PropertyConfigurator.configure(url);
		} catch (Exception e) {
			LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(e.getMessage()));
			StackTraceElement[] st = e.getStackTrace();
			int length = st.length;
			for (int cont = 0; cont < length; cont++) {
				LOGGER.error(st[cont]);
			}
		}
	}

	public static void debug(Class<?> clientLoggerClass, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).debug(StringUtil.sustituir(message, params));
		} catch (Exception e) {
			LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(StringUtil.sustituir(message, params)));
		}
	}

	public static void debug(Class<?> clientLoggerClass, Throwable throwable, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).debug(StringUtil.sustituir(message, params), throwable);
		} catch (Exception e) {
			defaultTrace(StringUtil.sustituir(message, params), throwable);
		}
	}

	public static void trace(Class<?> clientLoggerClass, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).trace(StringUtil.sustituir(message, params));
		} catch (Exception e) {
			LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(StringUtil.sustituir(message, params)));
		}
	}

	public static void trace(Class<?> clientLoggerClass, Throwable throwable, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).trace(StringUtil.sustituir(message, params), throwable);
		} catch (Exception e) {
			defaultTrace(StringUtil.sustituir(message, params), throwable);
		}
	}

	public static void info(Class<?> clientLoggerClass, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).info(StringUtil.sustituir(message, params));
		} catch (Exception e) {
			LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(StringUtil.sustituir(message, params)));
		}
	}

	public static void info(Class<?> clientLoggerClass, Throwable throwable, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).info(StringUtil.sustituir(message, params), throwable);
		} catch (Exception e) {
			defaultTrace(StringUtil.sustituir(message, params), throwable);
		}
	}

	public static void warn(Class<?> clientLoggerClass, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).warn(StringUtil.sustituir(message, params));
		} catch (Exception e) {
			LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(StringUtil.sustituir(message, params)));
		}
	}

	public static void warn(Class<?> clientLoggerClass, Throwable throwable, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).warn(StringUtil.sustituir(message, params), throwable);
		} catch (Exception e) {
			LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(StringUtil.sustituir(message, params)));
			defaultTrace(StringUtil.sustituir(message, params), throwable);
		}
	}

	public static void error(Class<?> clientLoggerClass, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).error(StringUtil.sustituir(message, params));
		} catch (Exception e) {
			LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(StringUtil.sustituir(message, params)));
		}
	}

	public static void error(Class<?> clientLoggerClass, Throwable throwable, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).error(StringUtil.sustituir(message, params), throwable);
		} catch (Exception e) {
			defaultTrace(StringUtil.sustituir(message, params), throwable);
		}
	}

	public static void fatal(Class<?> clientLoggerClass, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).fatal(StringUtil.sustituir(message, params));
		} catch (Exception e) {
			LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(StringUtil.sustituir(message, params)));
		}
	}

	public static void fatal(Class<?> clientLoggerClass, Throwable throwable, String message, Object... params) {
		try {
			Logger.getLogger(clientLoggerClass).fatal(StringUtil.sustituir(message, params), throwable);
		} catch (Exception e) {
			defaultTrace(StringUtil.sustituir(message, params), throwable);
		}
	}

	public static boolean isDebugEnabled(Class<?> clientLoggerClass) {
		try {
			return Logger.getLogger(clientLoggerClass).isDebugEnabled();
		} catch (Exception e) {
		}
		return false;
	}

	public static boolean isTraceEnabled(Class<?> clientLoggerClass) {
		try {
			return isEnabledFor(clientLoggerClass, 5000);
		} catch (Exception e) {
		}
		return false;
	}

	public static boolean isInfoEnabled(Class<?> clientLoggerClass) {
		try {
			return Logger.getLogger(clientLoggerClass).isInfoEnabled();
		} catch (Exception e) {
		}
		return false;
	}

	public static boolean isWarnEnabled(Class<?> clientLoggerClass) {
		try {
			return isEnabledFor(clientLoggerClass, 30000);
		} catch (Exception e) {
		}
		return false;
	}

	private static boolean isEnabledFor(Class<?> clientLoggerClass, int level) {
		try {
			return Logger.getLogger(clientLoggerClass).getEffectiveLevel()
					.toInt() <= level;
		} catch (Exception e) {
		}
		return false;
	}

	private static void defaultTrace(Object message, Throwable throwable) {
		LOGGER.error(new StringBuilder(DEFAULT_ERR_MSG).append(message.toString()));
		StackTraceElement[] st = throwable.getStackTrace();
		int length = st.length;
		for (int cont = 0; cont < length; cont++) {
			LOGGER.error(st[cont]);
		}
	}

}
